/* eslint-disable no-void */
/*
 * @Author: askMeWhy
 * @Date:   2018-07-05 09:47:04
 * @Last Modified by: AskMeWhy
 * @Last Modified time: 2021-02-08 10:43:39
 */
import { merge, ajax } from "@/utils";
import API_CONFIG from "./api";
import { API_DEFAULT_CONFIG } from "./config";

/**
 * 接口类
 * @DateTime 2018-07-05
 * 向外暴露 server 和 info 属性
 *
 * 调用方式
 * import Api from '@/services'
 *
 * Api.server['namespace/name']()
 * 该属性使用API_CONFIG里的配置属性封装了请求方式 最终返回一个Promise
 * Api.info['namespace/name']
 * 该属性会直接返回API_CONFIG里的配置属性，并每个配置项会多返回completePath
 * completePath: 是baseUrl加上配置的path的完整路径
 *
 */
import store from "@/store";

class ServiceInstance {
    server: any = {};
    info: any = {};
    baseUrl = "";
    authUrl = "";

    constructor(options: any) {
        this.baseUrl = options.BaseURL || "";
        this.authUrl = options.AuthURL || "";
        this.apiBuild(options);
    }

    apiBuild(apiOptions: any = {}) {
        const { BaseURL = "", MockURL = "", config = {} } = apiOptions;
        const _self = this;
        Object.keys(config).map(once => {
            const cur = config[once];
            const {
                name,
                data,
                queryString,
                method,
                path,
                namespace,
                mock,
                headers,
                setCommonParam,
                preFixUrl
            } = cur;
            const apiName = `${namespace ? namespace + "/" : ""}${name}`;
            let url = "";
            if (mock !== void 0 && mock.open) {
                url = `${MockURL}${mock.path}`;
            } else {
                url = `${apiOptions[preFixUrl] || BaseURL}${path}`;
            }
            Object.defineProperty(this.server, apiName, {
                value(
                    _params = {
                        data: {},
                        headers: {},
                        params: {},
                        loader: true,
                        responseType: "json",
                        cancelToken: null
                    }
                ) {
                    let _p = {};
                    if (Array.isArray(_params.data)) {
                        _p = merge(true, [], data, _params.data || []);
                    } else if (typeof _params.data === "string") {
                        _p = _params.data || "";
                    } else if (
                        Object.prototype.toString.call(_params.data) ===
                        "[object FormData]"
                    ) {
                        _p = _params.data;
                    } else {
                        _p = merge(true, {}, data, _params.data || {});
                    }
                    const _o = merge(
                        true,
                        {},
                        headers || {},
                        _params.headers || {}
                    );
                    let _url = url;
                    if (_self.hasUrlParams(_url)) {
                        _url = _self.buildUrlParams(
                            url,
                            _params.params,
                            apiName
                        );
                    }

                    if (setCommonParam) {
                        const user = store.getters.getUser;
                        if (user.isSignIn) {
                            _o.Authorization = "Bearer " + user.auth.token;
                            const _authArea: any = store.getters.getAuthArea;
                            _o.governmentId = [null, undefined].includes(
                                _authArea.governmentId
                            )
                                ? ""
                                : _authArea.governmentId;
                            // _o.governmentId = 1;
                            _o.departmentId = _authArea.departmentId || "";
                            _o.orgCategoryId = _authArea.orgCategoryId || "";
                            _o.cityCode = _authArea.cityCode || "";
                            // console.log(_url, _authArea.orgCategoryId || "");
                        }
                    }
                    return ajax({
                        method: method,
                        url: _url,
                        data: _p,
                        params: !!queryString,
                        loader:
                            _params.loader === void 0 ? true : _params.loader,
                        headers: {
                            ..._o
                        },
                        cancelToken: _params.cancelToken,
                        responseType: _params.responseType
                    });
                }
            });
            Object.defineProperty(this.info, apiName, {
                value: {
                    completePath: url,
                    ...cur
                }
            });
        });
    }

    hasUrlParams(url: string) {
        const reg = /\/:\w*/g;
        return url.match(reg) !== null;
    }

    buildUrlParams(url: string, params: any, apiName: string) {
        if (params === void 0) {
            throw Error(`请传入"${apiName}"已配置的params`);
        }
        const reg = /\/:\w*/g;
        const u = url.replace(reg, function(p) {
            const key = p.substring(2);
            if (params[key] === void 0) {
                throw Error(`"${apiName}"必须包含已配置的"${key}"`);
            }
            return "/" + params[key];
        });
        return u;
    }
}
console.log(API_DEFAULT_CONFIG);

export default new ServiceInstance({
    config: API_CONFIG,
    ...API_DEFAULT_CONFIG
});
